package com.example.testdemo.video_progress;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.media.AudioManager;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;

/**
 * Created by 颜 on 05.08.008.
 * 抖音进度条
 */

public class DouYinBar extends View {
    private static final String TAG = "DouYinBar";
    public static final int STATUS_DEFAULT_ING = 0;//默认情况下
    public static final int STATUS_BUFFER_ING = 1;//缓冲中
    public static final int STATUS_VOLUME_ING = 2;//调节音量中
    public static final int STATUS_PLAYER_ING = 3;//播放中
    private Context context;

    private Paint backPaint;//背景画笔
    private Paint bufferPaint;//缓冲画笔
    private Paint volumePaint;//音量画笔
    private Paint progressPaint;//进度画笔

    private RectF backRectF;//背景区域
    private RectF bufferRectF;//缓冲区域
    private RectF volumeRectF;//音量区域
    private RectF progressRectF;//进度区域

    private int progress;//进度
    private int duration;//总进度（时长）

    private int currentVolume;//当前音量
    private int maxVolume;//最大音量
    private AudioManager volumeManager;//音量管理器

    private int CURRENT_STATUS = STATUS_DEFAULT_ING;//当前状态

    private int bufferSpeed = 30;//缓冲动画速度
    private int bufferAlphaSpacing = 10;//缓冲透明度调整间隔
    private long recordKeyDownTime;//记录按钮按下的时间
    private int currentRecordStatus;//当前记录的状态

    public DouYinBar(Context context) {
        super(context);
    }

    public DouYinBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public DouYinBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    private void init(Context context) {
        this.context = context;
        initAudioManager();
        initPaint();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        initRectF();
    }

    /**
     * 初始化音频管理器
     */
    private void initAudioManager() {
        //获取音频管理器
        volumeManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        if (volumeManager != null) {
            //获取当前音量
            currentVolume = volumeManager.getStreamVolume(AudioManager.STREAM_MUSIC);
            //获取最大音量
            maxVolume = volumeManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
            Log.e(TAG, "当前音量 " + currentVolume + "  最大音量 " + maxVolume);
        }
    }

    /**
     * 初始化画笔
     */
    private void initPaint() {
        //初始化背景（基础线）画笔
        backPaint = new Paint();
        backPaint.setColor(Color.WHITE);
        backPaint.setAlpha(255 / 100 * 30);
        //初始化缓冲画笔
        bufferPaint = new Paint();
        bufferPaint.setColor(Color.WHITE);
        //初始化音量画笔
        volumePaint = new Paint();
        volumePaint.setColor(Color.YELLOW);
        //初始化进度画笔
        progressPaint = new Paint();
        progressPaint.setColor(Color.WHITE);
    }


    /**
     * 初始化区域信息
     */
    private void initRectF() {
        //初始化背景区域
        backRectF = new RectF(0, 0, getWidth(), getHeight());
        //初始化缓冲区域
        bufferRectF = new RectF(getWidth() / 2, 0, getWidth() / 2, getHeight());
        //初始化音量区域
        volumeRectF = new RectF(0, 0, currentVolumePx(), getHeight());
        //初始化进度区域
        progressRectF = new RectF(0, 0, currentProgressPx(), getHeight());
    }

    /**
     * 计算当前音量占屏幕的像素值
     *
     * @return 当前音量px
     */
    private float currentVolumePx() {
        float volumeScale = (float) getWidth() / (float) maxVolume;
        return currentVolume * volumeScale;
    }

    /**
     * 计算当前进度所占屏幕像素值
     *
     * @return 当前进度px
     */
    private float currentProgressPx() {
        if (duration == 0 || progress == 0) return 0;
        float progressScale = (float) getWidth() / (float) duration;
        return progress * progressScale;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画背景（基础线）
        canvas.drawRect(backRectF, backPaint);
        switch (CURRENT_STATUS) {
            case STATUS_DEFAULT_ING://默认情况下，啥也没有，只有一个基线，即背景
                break;
            case STATUS_BUFFER_ING://缓冲中，画缓冲线，需要反复调整区域来实现动画效果
                drawBufferLine(canvas);
                break;
            case STATUS_VOLUME_ING://音量调节，当音量按钮触发时响应
                drawVolumeLine(canvas);
                break;
            case STATUS_PLAYER_ING://播放时，画进度
                drawProgressLine(canvas);
                break;
            default:
                throw new RuntimeException("Without this parameter,CURRENT_STATUS is an exception");
        }
    }

    /**
     * 画缓冲线
     *
     * @param canvas 画布
     */
    private void drawBufferLine(Canvas canvas) {
        //如果边界小于 20 画透明状态，否则放大边界，左边再靠左，右边再靠右
        if (bufferRectF.left <= 20) {
            if (bufferPaint.getAlpha() < 20) {
                bufferRectF.left = getWidth() / 2;
                bufferRectF.right = getWidth() / 2;
                bufferPaint.setAlpha(255);
            } else {
                //改变画笔透明度
                bufferPaint.setAlpha(bufferPaint.getAlpha() - bufferAlphaSpacing);
            }
        } else {
            bufferRectF.left -= bufferSpeed;
            bufferRectF.right += bufferSpeed;
        }
        //画缓冲线
        canvas.drawRect(bufferRectF, bufferPaint);
        postInvalidate();
    }


    /**
     * 画音量线
     *
     * @param canvas 画布
     */
    private void drawVolumeLine(Canvas canvas) {
        if (System.currentTimeMillis() - recordKeyDownTime > 1000) {
            CURRENT_STATUS = currentRecordStatus;
        } else {
            volumeRectF.right = currentVolumePx();
            canvas.drawRect(volumeRectF, volumePaint);
        }
        postInvalidate();
    }

    /**
     * 画进度线
     *
     * @param canvas 画布
     */
    private void drawProgressLine(Canvas canvas) {
        progressRectF.right = currentProgressPx();
        Log.e(TAG, "画进度线：" + progressRectF.right);
        canvas.drawRect(progressRectF, progressPaint);
    }


    /**
     * 设置状态
     *
     * @param currentStatus 当前状态
     */
    public void setStatus(int currentStatus) {
        CURRENT_STATUS = currentRecordStatus = currentStatus;
        postInvalidate();
    }

    /**
     * 设置时长
     */
    public void setDuration(int duration) {
        this.duration = duration;
    }

    /**
     * 设置当前进度
     */
    public void setProgress(int progress) {
        this.progress = progress;
        CURRENT_STATUS = currentRecordStatus = STATUS_PLAYER_ING;
        postInvalidate();
    }

    /**
     * 调整音量
     * 调高音量 AudioManager.ADJUST_RAISE
     * 调低音量 AudioManager.ADJUST_LOWER
     */
    private void adjustVolume(int adjustType) {
        volumeManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, adjustType, 0);
        currentVolume = volumeManager.getStreamVolume(AudioManager.STREAM_MUSIC);
    }

    /**
     * 改变当前状态为调整音量状态
     * 如果当前状态已经是调整音量状态，则不改变记录的状态
     */
    private void changeCurrentStateForVolumeIng() {
        if (CURRENT_STATUS != STATUS_VOLUME_ING) {
            currentRecordStatus = CURRENT_STATUS;
        }
        CURRENT_STATUS = STATUS_VOLUME_ING;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {//音量加
            changeCurrentStateForVolumeIng();
            recordKeyDownTime = System.currentTimeMillis();
            adjustVolume(AudioManager.ADJUST_RAISE);
            postInvalidate();
            return true;
        }

        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {//音量减
            changeCurrentStateForVolumeIng();
            recordKeyDownTime = System.currentTimeMillis();
            adjustVolume(AudioManager.ADJUST_LOWER);
            postInvalidate();
            return true;
        }

        if (keyCode == KeyEvent.KEYCODE_BACK) {//监听返回键
            ((Activity) context).finish();
        }
        return false;
    }

}
